home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / New System Software Extensions / QuickDraw™ GX v1.0ß2 / Sample Code / Printing Samples / Printer Drivers… / ImageWriterLQ / DialogRoutines.c < prev    next >
Encoding:
Text File  |  1993-09-13  |  22.4 KB  |  824 lines  |  [TEXT/MPS ]

  1. /*---------------------------------------------------------------------------
  2. FILENAME
  3.     DialogRoutines.c
  4.  
  5. DESCRIPTION
  6.     This file contains the routines which are used to process the LQ driver's
  7.     sheetfeeder dialog.
  8.         
  9.     9/13/93 - dmh - Modified for the b2 seed.
  10.     
  11. COPYRIGHT
  12.     Copyright Apple Computer, Inc. 1992
  13.     All rights reserved. 
  14.     
  15. INTERFACE ROUTINES:
  16.     DoSheetfeederDialog
  17.  
  18. -------------------------------------------------------------------------------- */
  19.  
  20. // Include the standard Mac header files 
  21. #include "MacIncludes.h"
  22.  
  23. // Include the new QuickDraw GX graphics header files 
  24. #include <graphics routines.h>
  25. #include <graphics libraries.h>
  26. #include <math routines.h>
  27. #include <qd library.h>
  28.  
  29. // Include the required Printing Manager header files 
  30. #include <PrintingManager.h>
  31. #include <PrintingMessages.h>
  32. #include <PrintingDrivers.h>
  33. #include <Collections.h>
  34. #include <Messages.h>
  35. #include <PrintingResTypes.h>
  36. #include <PrintingErrors.h>
  37.  
  38. #include <Exceptions.h>
  39.  
  40. // Include the internal driver constants and types used by this module 
  41. #include "Resources.h"
  42. #include "UniversalMessageIntf.h"
  43. #include "DialogRoutines.h"
  44.  
  45.  
  46. /***************************************************************************************
  47. *                                                 CONSTANTS                                                         *
  48. ***************************************************************************************/                        
  49.  
  50. // Constants for accessing items in the Sheetfeeder dialog
  51.  
  52. #define    kTray1Item                4            //    Tray #1 pop-up menu
  53. #define    kTray2Item                5            //    Tray #2 pop-up menu
  54. #define    kTray3Item                6            //    Tray #3 pop-up menu
  55. #define    kPrinterPICTItem        7            //    Picture of the printer with a sheetfeeder
  56.  
  57. // Constants useful for filtering events
  58.  
  59. #define    kENTER                    0x03        // ENTER character
  60. #define    kCR                        0x0D        // Carriage return character
  61.  
  62. // Constants defining the maximum paper size supported by the LQ printer
  63.  
  64. #define    kMaxPaperWidth            ff(15)    // 15 inches is maximum width
  65. #define    kMaxPaperHeight            ff(69)    // 69 inches is maximum height
  66.  
  67.  
  68. /*********************************************************************************
  69.  *                                             TYPES                                                     *
  70.  *********************************************************************************/
  71.  
  72. // PopupMenuInfo - Structure used to initialize the tray pop-up menus 
  73.  
  74. typedef struct
  75. {
  76.     short            numTrays;        // Number of trays configured on the printer 
  77.     MenuHandle        tray1Menu;        //    handle to the tray #1 pop-up menu
  78.     MenuHandle        tray2Menu;        //    handle to the tray #2 pop-up menu
  79.     MenuHandle        tray3Menu;        //    handle to the tray #3 pop-up menu
  80. }    PopupMenuInfo,
  81.     *PopupMenuInfoPtr;
  82.     
  83.     
  84. // PaperSearchRec - Structure used to search for a paper type chosen from a pop-up menu
  85.  
  86. typedef struct
  87. {
  88.     gxPaperType            paper;            // temp. paper type reference in which to return found paper type 
  89.     Str31                paperName;        //    name of the paper to locate
  90. }    PaperSearchRec,
  91.     *PaperSearchRecPtr;
  92.     
  93.     
  94. // PopupPrivateData - Structure defining a pop-up control's private data
  95.  
  96. typedef struct
  97. {
  98.     MenuHandle        mHandle;            // handle to the menu 
  99.     short                mID;                //    menu ID
  100.     char                mPrivate[0];    //    reserved
  101. }    PopupPrivateData,
  102.     *PopupPrivateDataPtr,
  103.     **PopupPrivateDataHdl;
  104.         
  105.  
  106. /***************************************************************************************
  107. *                                         INLINE ROUTINES                                                         *
  108. ***************************************************************************************/                        
  109.  
  110. pascal void QDDrawPicture(PicHandle myPicture,const Rect *dstRect) = 0xA8F6;
  111.  
  112.  
  113. /***************************************************************************************
  114. *                                         INTERNAL ROUTINES                                                     *
  115. ***************************************************************************************/                        
  116.  
  117.  
  118. /****************************************************************************************
  119.  
  120.                             FindChosenPaperType
  121.                             
  122.     function:
  123.                 This routine is called by GXForEachPaperTypeDo, and it searches for a specific
  124.                 paper type (by name).  It terminates searching when the paper type is 
  125.                 found.  Only the names of paper that will fit into the printer will be considered.
  126.  
  127.                 
  128.     parameters:                
  129.                 paper                target paper type
  130.                 paperToFind        structure that identifies the paper type to find
  131.                 
  132.     returns:
  133.                 gxLoopStatus        gxKeepLooping => keep examining paper types
  134.                                     gxStopLooping    => no longer loop - we found the one we wanted
  135.     
  136. ****************************************************************************************/
  137. pascal gxLoopStatus FindChosenPaperType(gxPaperType paper, PaperSearchRecPtr paperToFind)
  138. {
  139.     Str31            paperName;
  140.     gxLoopStatus    status = gxKeepLooping;
  141.     gxRectangle        paperSize;
  142.     
  143.     // Get the dimensions of the paper
  144.     GXGetPaperTypeDimensions(paper, nil, &paperSize);
  145.     
  146.     // Will the paper fit into the printer?
  147.     if (    ( (paperSize.right - paperSize.left) <= FixMul(ff(72), kMaxPaperWidth) )    &&
  148.             ( (paperSize.bottom - paperSize.top) <= FixMul(ff(72), kMaxPaperHeight) )
  149.         )
  150.     {
  151.         // Retrieve the name of the paper type
  152.         GXGetPaperTypeName(paper, paperName);
  153.     
  154.         if ( IUCompString(paperName, paperToFind->paperName) == 0 )    //    T => Found the paper type
  155.         {
  156.             // Make a copy of this paper type and quit searching
  157.             GXCopyPaperType (paper, paperToFind->paper);
  158.             status = gxStopLooping;
  159.         }
  160.     }
  161.         
  162.     return(status);
  163. /* FindChosenPaperType */
  164.  
  165.  
  166. /****************************************************************************************
  167.  
  168.                             SaveSheetfeederSettings
  169.                             
  170.     function:
  171.                 This routine is called if the user confirms the changes in the dialog.  It
  172.                 stores updates the tray information configuration file with the user's latest
  173.                 settings.
  174.                 
  175.     parameters:                
  176.                 theDlog        pointer to the target dialog
  177.                 menuStuff    info. about the pop-up menus
  178.                 
  179.     returns:
  180.                 OSErr            error code
  181.     
  182. ****************************************************************************************/
  183. OSErr SaveSheetfeederSettings(DialogPtr theDlog, PopupMenuInfoPtr menuStuff)
  184. {
  185.     OSErr            anErr;
  186.     gxPaperType        paper;
  187.     gxJob            theJob = GXGetJob();
  188.     MenuHandle        *nextMenu;
  189.     short            i;
  190.     
  191.     // Create a temporary paper type
  192.     
  193.     paper = GXNewPaperType(theJob, NULL, NULL, NULL);
  194.     anErr = GXGetJobError(theJob);
  195.     require(anErr == noErr, GXNewPaperType);
  196.     
  197.     // For each visible pop-up menu, update its associated tray information
  198.     
  199.     for (i = kTray1Item, nextMenu = &(menuStuff->tray1Menu); i <= kTray3Item; ++i, ++nextMenu )
  200.     {
  201.         short        whichTray = i - kTray1Item + 1;
  202.         
  203.         if ( whichTray <= menuStuff->numTrays )    //    T => This menu is visible
  204.         {
  205.             Str31                    paperName;
  206.             short                    itemType;
  207.             ControlHandle        item;
  208.             Rect                    itemRect;
  209.             PaperSearchRec        paperToFind;
  210.             
  211.             // Get the name of the chosen paper type from the menu
  212.             
  213.             GetDItem(theDlog, i, &itemType, (Handle *) &item, &itemRect);
  214.             GetItem(*nextMenu, GetCtlValue(item), paperName);
  215.  
  216.             // Get the tray information for this tray
  217.             
  218.             anErr = GXGetTrayPaperType(whichTray, paper);
  219.             if (anErr == resNotFound)
  220.                 anErr = noErr;
  221.             else {
  222.                 require(anErr == noErr, GXGetTrayPaperType);
  223.             
  224.                 //    Get the referenced paper type
  225.     
  226.                 paperToFind.paper = paper;
  227.                 BlockMove((Ptr) paperName, (Ptr) paperToFind.paperName, sizeof(Str31));
  228.                 
  229.                 GXForEachJobPaperTypeDo(theJob, FindChosenPaperType, &paperToFind, false);        // Don't consider the format device in this search    
  230.                 anErr = GXGetJobError(theJob);
  231.                 require(anErr == noErr, GXForEachPaperTypeDo);
  232.                 
  233.                 // Update the paper type for this tray
  234.                 
  235.                 anErr = GXSetTrayPaperType(whichTray, paper);
  236.                 require(anErr == noErr, GXSetTrayPaperType);
  237.             }
  238.         }
  239.         else    //     T => No more visible pop-up menus
  240.             break;
  241.     }
  242.  
  243.  
  244. /******* Clean-up *******/
  245.  
  246. GXSetTrayPaperType:
  247. GXGetTrayPaperType:
  248. GXForEachPaperTypeDo:
  249.     GXDisposePaperType(paper);
  250.  
  251. GXNewPaperType:
  252.     return(anErr);
  253. }
  254. /* SaveSheetfeederSettings */
  255.  
  256.  
  257. /****************************************************************************************
  258.  
  259.                             SheetfeederDialogFilter
  260.                             
  261.     function:
  262.                 This routine is the filter proc. that is passed to ModalDialog when the 
  263.                 sheetfeeder dialog is displayed.  It filters for the <cr> and <enter> keys
  264.                 and for command-".".
  265.                 
  266.     parameters:                
  267.                 theDlog        pointer to the target dialog
  268.                 theEvent        the event to be filtered
  269.                 itemHit        the item which was selected; may be mapped to ok or cancel
  270.                 
  271.     returns:
  272.                 Boolean        true if we've filtered the event; false if ModalDialog should process it
  273.     
  274. ****************************************************************************************/
  275. pascal Boolean SheetfeederDialogFilter(DialogPtr theDlog, EventRecord *theEvent, short *itemHit)
  276. {
  277.     Boolean        eventFiltered = false;
  278.     short        itemType;
  279.     Rect        itemRect;
  280.     Handle        item;
  281.     
  282.     if ( (theEvent->what == keyDown) || (theEvent->what == autoKey) ) 
  283.     {
  284.         char        c;
  285.         
  286.         c = (char) (theEvent->message & charCodeMask);
  287.         
  288.         if ( (c == kCR) || (c == kENTER) )     //    T => User typed carriage return or enter key; filter event
  289.         {
  290.             *itemHit = ok;
  291.             eventFiltered = true;
  292.         }
  293.         else
  294.         if ( (c == '.') && ((theEvent->modifiers & cmdKey) != 0) )    //    T => User typed <cmnd>-"."
  295.         {
  296.             *itemHit = cancel;
  297.             eventFiltered = true;
  298.         }
  299.         
  300.         if (eventFiltered)    //    T => Highlight the buttons appropriately
  301.         {
  302.             ControlHandle    theCtrl;
  303.             long                ignore;
  304.             
  305.             // Highlight the OK button momentarily
  306.             
  307.             GetDItem(theDlog, *itemHit, &itemType, (Handle *) &theCtrl, &itemRect);
  308.             HiliteControl(theCtrl, inButton);
  309.             Delay(10, &ignore);
  310.             HiliteControl(theCtrl, 0);
  311.         }
  312.     }
  313.     else
  314.     if (theEvent->what == updateEvt)    //    T => Outline the OK button
  315.     {
  316.         GrafPtr    oldPort;
  317.         
  318.         GetPort(&oldPort);
  319.         SetPort(theDlog);
  320.         
  321.         GetDItem(theDlog, ok, &itemType, &item, &itemRect);
  322.         PenSize(3, 3);
  323.         InsetRect(&itemRect, -4, -4);
  324.         FrameRoundRect(&itemRect, 16, 16);
  325.         PenNormal();
  326.  
  327.         SetPort(oldPort);
  328.     }
  329.  
  330.     return(eventFiltered);
  331. }
  332. /* SheetfeederDialogFilter */
  333.  
  334.  
  335. /****************************************************************************************
  336.  
  337.                             UniquePaperName
  338.                             
  339.     function:
  340.                 This routine searches for a specified paper type name in a specific pop-up
  341.                 menu.  If it finds the name, the routine returns false; otherwise it
  342.                 returns true.
  343.                 
  344.     parameters:                
  345.                 hMenu            handle to the menu to examine
  346.                 paperName    name of the paper type to insert to check for
  347.                 
  348.     returns:
  349.                 Boolean        true if paper type name is unique; false otherwise
  350.     
  351. ****************************************************************************************/
  352. Boolean UniquePaperName(MenuHandle hMenu, Str31 paperName)
  353. {
  354.     Boolean        isUnique = true;
  355.     short        i;
  356.     Str255        menuString;
  357.     
  358.     for (i = CountMItems(hMenu); i > 0; --i) 
  359.     {
  360.         GetItem(hMenu, i, menuString);
  361.         
  362.         if ( IUCompString(paperName, menuString) == 0 )     //    T => Found the string
  363.         {
  364.             isUnique = false;
  365.             break;
  366.         }
  367.     }
  368.     
  369.     return(isUnique);
  370. }  
  371. /* UniquePaperName */
  372.  
  373.  
  374. /****************************************************************************************
  375.  
  376.                             AddPaperName
  377.                             
  378.     function:
  379.                 This routine is called by GXForEachPaperTypeDo, and it adds a paper name to 
  380.                 each visible pop-up menu if the name does not already appear in the menu.
  381.                 Only the names of paper that will fit into the printer will be listed
  382.                 in the pop-up menu.
  383.                 
  384.     parameters:                
  385.                 paper                target paper type
  386.                 menuStuff        pointer to info about the dialog's pop-up menus
  387.                 
  388.     returns:
  389.                 gxLoopStatus        gxKeepLooping => examine all target paper types
  390.     
  391. ****************************************************************************************/
  392. pascal gxLoopStatus AddPaperName(gxPaperType paper, PopupMenuInfoPtr menuStuff)
  393. {
  394.     Str31            paperName;
  395.     gxRectangle        paperSize;
  396.     
  397.     // Get the dimensions of the paper
  398.     GXGetPaperTypeDimensions(paper, nil, &paperSize);
  399.     
  400.     // Will the paper fit into the printer?
  401.     if (    ( (paperSize.right - paperSize.left) <= FixMul(ff(72), kMaxPaperWidth) )    &&
  402.             ( (paperSize.bottom - paperSize.top) <= FixMul(ff(72), kMaxPaperHeight) )
  403.         )
  404.     {
  405.         // Retrieve the name of the paper type
  406.         GXGetPaperTypeName(paper, paperName);
  407.     
  408.         if ( UniquePaperName(menuStuff->tray1Menu, paperName) )    //    T => If the paper name is unique, add it
  409.         {
  410.             MenuHandle        *nextMenu;
  411.             Str255            theName;
  412.             short                i;
  413.             
  414.             // For each visible menu, add the name to the pop-up
  415.             
  416.             for (i = kTray1Item, nextMenu = &(menuStuff->tray1Menu); i <= kTray3Item; ++i, ++nextMenu )
  417.             {
  418.                 if ( (i - kTray1Item + 1) <= menuStuff->numTrays )    //    T => This menu is visible
  419.                 {
  420.                     AppendMenu(*nextMenu, "\p ");
  421.                     BlockMove(paperName, theName, sizeof(Str31));
  422.                     SetItem(*nextMenu, CountMItems(*nextMenu), theName);
  423.                 }
  424.                 else    //     T => No more visible pop-up menus
  425.                     break;
  426.             }
  427.         }
  428.     }
  429.         
  430.     return (gxKeepLooping);
  431. /* AddPaperName */
  432.  
  433.  
  434. /****************************************************************************************
  435.  
  436.                             LoadPaperNames
  437.                             
  438.     function:
  439.                 This routine loads the names of each uniquely named paper type into each of the
  440.                 tray pop-up menus that are still visible.
  441.                 
  442.     parameters:                
  443.                 pDlg            Pointer to the target dialog
  444.                 whichItem    Index in the DITL of the item to draw
  445.                 
  446.     returns:
  447.                 OSErr            error code
  448.     
  449. ****************************************************************************************/
  450. OSErr LoadPaperNames(DialogPtr theDlog, PopupMenuInfoPtr menuStuff)
  451. {
  452.     short                itemType;
  453.     Rect                itemRect;
  454.     ControlHandle        item;
  455.     short                i;
  456.     gxJob                theJob = GXGetJob();
  457.     OSErr                anErr;
  458.  
  459.     GXForEachJobPaperTypeDo(theJob,  AddPaperName,  menuStuff, false);        // Don't consider the format device in this search    
  460.     anErr = GXGetJobError(theJob);
  461.  
  462.     if (anErr == noErr)
  463.     {
  464.         MenuHandle        *nextMenu;
  465.         
  466.         // For each visible menu, initialize the pop-up control
  467.         
  468.         for (i = kTray1Item, nextMenu = &(menuStuff->tray1Menu); i <= kTray3Item; ++i, ++nextMenu )
  469.         {
  470.             if ( (i - kTray1Item + 1) <= menuStuff->numTrays )    //    T => This menu is visible
  471.             {
  472.                 GetDItem(theDlog, i, &itemType, (Handle *) &item, &itemRect);
  473.                 
  474.                 SetCtlMin(item, 1);
  475.                 SetCtlMax(item, CountMItems(*nextMenu));
  476.                 SetCtlValue(item, 1);
  477.             }
  478.             else    //     T => No more visible pop-up menus
  479.                 break;
  480.         }
  481.     }
  482.  
  483.     return(anErr);
  484. }
  485. /* LoadPaperNames */
  486.  
  487.  
  488. /****************************************************************************************
  489.  
  490.                             SheetfeederDrawProc
  491.                             
  492.     function:
  493.                 This routine is used to draw the picture of the sheetfeeder in the configuration
  494.                 dialog.
  495.                 
  496.     parameters:                
  497.                 pDlg            Pointer to the target dialog
  498.                 whichItem    Index in the DITL of the item to draw
  499.                 
  500.     returns:
  501.                 OSErr            error code
  502.     
  503. ****************************************************************************************/
  504. pascal void SheetfeederDrawProc(WindowPtr    pDlg, short whichItem)
  505. {
  506.     SpecGlobalsHdl     hGlobals = GetMessageHandlerInstanceContext();
  507.     Handle                hItem;
  508.     Rect                    itemRect;
  509.     short                    itemType;
  510.     
  511.     GetDItem(pDlg, whichItem, &itemType, &hItem, &itemRect);
  512.  
  513.     QDDrawPicture((*hGlobals)->sheetFeederPICT, &itemRect);
  514. }
  515. /* SheetfeederDrawProc */
  516.  
  517.  
  518. /****************************************************************************************
  519.  
  520.                             GetConfigInfo
  521.                             
  522.     function:
  523.                 This routine is a utility function that returns the LQ driver's configuration
  524.                 info. from the desktop printer file.
  525.                 
  526.     parameters:                
  527.                 configInfo    Latest info fetched from the DTP file
  528.                 
  529.     returns:
  530.                 OSErr            error code
  531.     
  532. ****************************************************************************************/
  533. OSErr GetConfigInfo(IWLQConfigInfoPtr configInfo)
  534. {
  535.     OSErr                        anErr;
  536.     Str32                        deviceName;
  537.     IWLQConfigInfoHdl            hConfigData;
  538.     
  539.     // Get the name of the desktop printer file
  540.     GXGetPrinterName(GXGetJobOutputPrinter(GXGetJob()), deviceName);
  541.  
  542.     // Get the config info
  543.     anErr = GXFetchDTPData(deviceName, kIWLQConfigType, kIWLQConfigID, (Handle *) &hConfigData);
  544.     require(anErr == noErr, GXFetchDTPData);
  545.     
  546.     // Return the config. info
  547.     *configInfo = **hConfigData;
  548.     
  549.     // Kill the temporary handle
  550.     DisposHandle((Handle) hConfigData);
  551.     
  552.  
  553. /******* Clean-up *******/
  554.  
  555. GXFetchDTPData:
  556.     return(anErr);
  557. }
  558. /* GetConfigInfo */
  559.  
  560.  
  561. /****************************************************************************************
  562.  
  563.                             InitSheetfeederDialog
  564.                             
  565.     function:
  566.                 This routine is called to initialize the sheet feeder dialog and to set the
  567.                 state of the pop-up menus based upon the latest configuration information.
  568.                 
  569.     parameters:                
  570.                 theDlog        returns the pointer to the dialog window if init. was succesful; otherwise nil
  571.                 menuStuff    info about the dialog's pop-up menus
  572.                 
  573.     returns:
  574.                 OSErr        error code
  575.     
  576. ****************************************************************************************/
  577. OSErr InitSheetfeederDialog(DialogPtr *theDlog, PopupMenuInfoPtr menuStuff)
  578. {
  579.     OSErr                anErr = noErr;
  580.     DialogPtr            dLog;
  581.     IWLQConfigInfo        configInfo;
  582.     SpecGlobalsHdl         hGlobals = GetMessageHandlerInstanceContext();
  583.     short                itemType;
  584.     Rect                itemRect;
  585.     Handle                hItem;
  586.     gxPaperType            paper;
  587.     
  588.     // Initialize variables
  589.     *theDlog = nil;
  590.     (*hGlobals)->sheetFeederPICT = nil;
  591.     
  592.     dLog = GetNewDialog(kSheetFeederDLOG, nil, (WindowPtr) (-1));
  593.     if (dLog == nil)
  594.     {
  595.         anErr = MemError();
  596.         if (anErr == noErr)
  597.             anErr = resNotFound;
  598.         
  599.         require(anErr == noErr, GetNewDialog);
  600.     }
  601.  
  602.     // Fetch the latest configuration info. from the DTP file
  603.     anErr = GetConfigInfo(&configInfo);
  604.     require(anErr == noErr, GetConfigInfo);
  605.     
  606.     // Determine which sheetfeeder picture to display in the dialog
  607.     {
  608.         short            whichPICT;
  609.         Handle            thePICT;
  610.         
  611.         switch (configInfo.numTrays)
  612.         {
  613.             case 1:    whichPICT = kOneTrayPICT;         break;
  614.             case 2:    whichPICT = kTwoTrayPICT;         break;
  615.             case 3:    whichPICT = kThreeTrayPICT;     break;
  616.         }
  617.         
  618.         anErr = Send_GXFetchTaggedDriverData('PICT', whichPICT, (Handle *) &thePICT);
  619.         require(anErr == noErr, GXFetchTaggedDriverData);
  620.         
  621.         // Save this handle in our globals
  622.  
  623.         HNoPurge(thePICT);
  624.         (*hGlobals)->sheetFeederPICT = (PicHandle) thePICT;
  625.         
  626.         // Setup the DrawProc for this picture item
  627.         
  628.         GetDItem(dLog, kPrinterPICTItem, &itemType, &hItem, &itemRect);
  629.         SetDItem(dLog, kPrinterPICTItem, itemType, (Handle) SheetfeederDrawProc, &itemRect);
  630.     }
  631.     
  632.     // Now fill in the pop-up menu paper type names and hide any pop-ups that don't apply
  633.     // to the current configuration
  634.     {
  635.         PopupPrivateDataHdl            privData;
  636.         short                        i;
  637.         MenuHandle                    *nextMenu;
  638.         
  639.         // Hide those pop-ups which don't apply to the current configuration
  640.         if (configInfo.numTrays < 3)
  641.         {
  642.             HideDItem(dLog, kTray3Item);
  643.         }
  644.  
  645.         if (configInfo.numTrays < 2)
  646.         {
  647.             HideDItem(dLog, kTray2Item);
  648.         }
  649.         
  650.         // Init. the menuStuff structure in order to load the paper names into the pop-ups
  651.         
  652.         menuStuff->numTrays = configInfo.numTrays;
  653.  
  654.         for (i = kTray1Item, nextMenu = &(menuStuff->tray1Menu); i <= kTray3Item; ++i, ++nextMenu)
  655.         {
  656.             GetDItem(dLog, i, &itemType, &hItem, &itemRect);
  657.             privData = (PopupPrivateDataHdl) (* (ControlHandle) hItem)->contrlData;
  658.             *nextMenu = (*privData)->mHandle;
  659.         }
  660.         
  661.         // Now load the paper type names into the remaining pop-up menus
  662.         anErr = LoadPaperNames(dLog, menuStuff);
  663.         require(anErr == noErr, LoadPaperNames);
  664.     }
  665.     
  666.     // Retrieve the latest paper<->tray configuration and force the pop-up(s) to display the
  667.     // correct paper name (i.e. the last selected paper name).
  668.     {
  669.         gxJob            theJob = GXGetJob();
  670.         MenuHandle    *nextMenu;
  671.         short            i;
  672.         
  673.         // Create a temporary paper type
  674.         
  675.         paper = GXNewPaperType(theJob, NULL, NULL, NULL);
  676.         anErr = GXGetJobError(theJob);
  677.         require(anErr == noErr, GXNewPaperType);
  678.         
  679.         // For each visible pop-up menu, try to display the last choosen paper type
  680.         
  681.         for (i = kTray1Item, nextMenu = &(menuStuff->tray1Menu); i <= kTray3Item; ++i, ++nextMenu )
  682.         {
  683.             short        whichTray = i - kTray1Item + 1;
  684.             
  685.             if ( whichTray <= menuStuff->numTrays )    //    T => This menu is visible
  686.             {
  687.                 Str255    menuString;
  688.                 short        j;
  689.                 Str31        paperName;
  690.                 
  691.                 // Get the tray information for this tray
  692.                 
  693.                 anErr = GXGetTrayPaperType(whichTray, paper);
  694.                 if (anErr == resNotFound)
  695.                     anErr = noErr;
  696.                 else {
  697.                     require(anErr == noErr, GXGetTrayPaperType);
  698.                 
  699.                     // Fetch the name of the paper type
  700.                     GXGetPaperTypeName(paper, paperName);
  701.                     
  702.                     // For each paper name in the menu, try to find a match
  703.                     
  704.                     for (j = CountMItems(*nextMenu); j > 0; --j) 
  705.                     {
  706.                         GetItem(*nextMenu, j, menuString);
  707.                         
  708.                         if ( IUCompString(paperName, menuString) == 0 )     //    T => Found the string
  709.                         {
  710.                             //    Make this paper name the current pop-up menu selection
  711.                             
  712.                             GetDItem(dLog, i, &itemType, &hItem, &itemRect);
  713.                             SetCtlValue((ControlHandle) hItem, j);
  714.                             break;
  715.                         }
  716.                     }
  717.                 }
  718.             }
  719.             else    //     T => No more visible pop-up menus
  720.                 break;
  721.         }
  722.  
  723.         // Dump the temporary paper type
  724.         GXDisposePaperType(paper);
  725.     }
  726.     
  727.     *theDlog = dLog;
  728.     
  729.     return(anErr);
  730.     
  731.     
  732. /******* Clean-up *******/
  733.  
  734. GXGetTrayPaperType:
  735.     GXDisposePaperType(paper);
  736.  
  737. GXNewPaperType:
  738. LoadPaperNames:
  739.     DisposHandle((Handle) (*hGlobals)->sheetFeederPICT);
  740.     
  741. GXFetchTaggedDriverData:
  742. GetConfigInfo:
  743.     DisposDialog(dLog);
  744.     
  745. GetNewDialog:
  746.     return(anErr);
  747. }
  748. /* InitSheetfeederDialog */
  749.  
  750.  
  751. /***************************************************************************************
  752. *                                         INTERFACE ROUTINES                                                     *
  753. ***************************************************************************************/                        
  754.  
  755. /****************************************************************************************
  756.  
  757.                             DoSheetfeederDialog
  758.                             
  759.     function:
  760.                 This routine is called to display and process the LQ driver's sheetfeeder
  761.                 dialog.  This dialog is displayed when the user selects the "Input Trays…" menu
  762.                 item from the Finder menu.  This dialog allows the user to specify the type
  763.                 of paper that's contained within the printer's sheet feeder.
  764.                 
  765.     parameters:                
  766.                 None
  767.                 
  768.     returns:
  769.                 OSErr        error code
  770.     
  771. ****************************************************************************************/
  772. OSErr DoSheetfeederDialog(void)
  773. {
  774.     OSErr                    anErr = noErr;
  775.     GrafPtr                    oldPort;
  776.     DialogPtr                theDlog;
  777.     short                    itemHit = 0;
  778.     PopupMenuInfo            menuStuff;
  779.     SpecGlobalsHdl             hGlobals = GetMessageHandlerInstanceContext();
  780.     
  781.     GetPort(&oldPort);
  782.     
  783.     // Initialize the dialog before displaying it
  784.     anErr = InitSheetfeederDialog(&theDlog, &menuStuff);
  785.     require(anErr == noErr, InitSheetfeederDialog);
  786.     
  787.     // Make sure the dialog is now visible
  788.     ShowWindow(theDlog);
  789.     SelectWindow(theDlog);
  790.     
  791.     // Process events in the window
  792.     while ( (itemHit != ok) && (itemHit != cancel) )
  793.     {
  794.        ModalDialog((ModalFilterProcPtr) SheetfeederDialogFilter, &itemHit);
  795.     }
  796.  
  797.     //    Do we need to save the new settings?
  798.     if (itemHit == ok)
  799.         anErr = SaveSheetfeederSettings(theDlog, &menuStuff);
  800.         
  801.     // Dump the dialog and picture handle
  802.     
  803.     if ( (*hGlobals)->sheetFeederPICT != nil )
  804.         DisposHandle((Handle) (*hGlobals)->sheetFeederPICT);
  805.         
  806.     DisposDialog(theDlog);
  807.     
  808.     SetPort(oldPort);
  809.  
  810.     return(anErr);
  811.     
  812.     
  813. /******* Clean-up *******/
  814.  
  815. InitSheetfeederDialog:
  816.     SetPort(oldPort);
  817.     
  818.     return(anErr);
  819. }
  820. /* DoSheetfeederDialog */
  821.  
  822.